﻿using EYangFramework.Common.Ninject;
using EYangFramework.Domain.Entitys.Entrys;
using EYangFramework.Domain.Entitys.ValueObjects;
using EYangFramework.Domain.Repositorys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EYangFramework.Domain.Services
{
    [AutoBind]
    public class AuthManagerService : IAuthManagerService
    {
        IRepository<User> RepositoryUser { get; set; }
        IRepository<Role> RepositoryRole { get; set; }
        IRepository<Navigation> RepositoryNavigation { get; set; }
        IRepository<Menu> RepositoryMenu { get; set; }
        public AuthManagerService(IRepository<User> repositoryUser, IRepository<Role> repositoryRole, IRepository<Navigation> repositoryNavigation, IRepository<Menu> repositoryMenu)
        {
            this.RepositoryUser = repositoryUser;
            this.RepositoryRole = repositoryRole;
            this.RepositoryNavigation = repositoryNavigation;
            this.RepositoryMenu = repositoryMenu;
        }

        public bool UpdateRoleNavigations(List<Navigation> selectedNavigations, string roleName)
        {
            var currentRole = RepositoryRole.FirstOrDefault(t => t.ROLENAME == roleName);
            //首先获取到当前角色所拥有的导航权限
            List<Navigation> currentRoleNavigations = RepositoryNavigation.GetAllListNoTracking(t => t.ROLES.Any(r => r.ROLENAME == roleName));
            //遍历所有的选中的导航
            foreach (var item in selectedNavigations)
            {
                if (currentRoleNavigations.Any(t => t.NAVIGATIONNAME == item.NAVIGATIONNAME))
                {
                    //将当前的所拥有的导航删除
                    currentRoleNavigations.RemoveAll(t => t.NAVIGATIONNAME == item.NAVIGATIONNAME);
                    continue;
                }
                //如果已拥有的导航中不包含选中的导航,则添加这个导航
                var addNavigation = RepositoryRole.DbContext.Set<Navigation>().Where(t => t.NAVIGATIONNAME == item.NAVIGATIONNAME).FirstOrDefault();
                currentRole.NAVIGATIONS.Add(addNavigation == null ? item : addNavigation);
            }
            //将取消权限的导航删除
            foreach (var item in currentRoleNavigations)
            {
                //保证在同一个上下文中
                var removeNavigation = RepositoryRole.DbContext.Set<Navigation>().Where(t => t.NAVIGATIONNAME == item.NAVIGATIONNAME).FirstOrDefault();
                currentRole.NAVIGATIONS.Remove(removeNavigation);
            }
            RepositoryRole.Update(currentRole);//更新角色
            return true;
        }

        public bool UpdateRoleMenus(List<Menu> selectedMenus, string roleName)
        {
            var currentRole = RepositoryRole.FirstOrDefault(t => t.ROLENAME == roleName);
            List<Menu> currentRoleMenus = RepositoryMenu.GetAllListNoTracking(t => t.ROLES.Any(r => r.ROLENAME == roleName));
            foreach (var item in selectedMenus)
            {
                if (currentRoleMenus.Any(t => t.MENUNAME == item.MENUNAME && t.FORMTYPE==item.FORMTYPE))
                {
                    currentRoleMenus.RemoveAll(t => t.MENUNAME == item.MENUNAME && t.FORMTYPE == item.FORMTYPE);
                    continue;
                }
                var addMenu= RepositoryRole.DbContext.Set<Menu>().Where(t => t.MENUNAME == item.MENUNAME && t.FORMTYPE == item.FORMTYPE).FirstOrDefault();
                currentRole.MENUS.Add(addMenu == null ? item : addMenu);
            }
            foreach (var item in currentRoleMenus)
            {
                var removeMenu = RepositoryRole.DbContext.Set<Menu>().Where(t => t.MENUNAME == item.MENUNAME && t.FORMTYPE == item.FORMTYPE).FirstOrDefault();
                currentRole.MENUS.Remove(removeMenu);
            }
            RepositoryRole.Update(currentRole);//更新角色
            return true;
        }

        public bool UpdateUserNavigations(List<Navigation> selectedNavigations, string userName)
        {
            var currentUser = RepositoryUser.FirstOrDefault(t => t.USERNAME == userName);
            List<Navigation> currentUserNavigations = RepositoryNavigation.GetAllListNoTracking(t => t.USERS.Any(r => r.USERNAME == userName));
            foreach (var item in selectedNavigations)
            {
                if (currentUserNavigations.Any(t => t.NAVIGATIONNAME == item.NAVIGATIONNAME))
                {
                    currentUserNavigations.RemoveAll(t => t.NAVIGATIONNAME == item.NAVIGATIONNAME);
                    continue;
                }
                var addNavigation = RepositoryRole.DbContext.Set<Navigation>().Where(t => t.NAVIGATIONNAME == item.NAVIGATIONNAME).FirstOrDefault();
                currentUser.NAVIGATIONS.Add(addNavigation == null ? item : addNavigation);
            }
            foreach (var item in currentUserNavigations)
            {
                var removeNavigation = RepositoryUser.DbContext.Set<Navigation>().Where(t => t.NAVIGATIONNAME == item.NAVIGATIONNAME).FirstOrDefault();
                currentUser.NAVIGATIONS.Remove(removeNavigation);
            }
            RepositoryUser.Update(currentUser);//更新角色
            return true;
        }

        public bool UpdatUserMenus(List<Menu> selectedMenus, string userName)
        {
            var currentUser = RepositoryUser.FirstOrDefault(t => t.USERNAME == userName);
            List<Menu> currentUserMenus = RepositoryMenu.GetAllListNoTracking(t => t.USERS.Any(r => r.USERNAME == userName));
            foreach (var item in selectedMenus)
            {
                if (currentUserMenus.Any(t => t.MENUNAME == item.MENUNAME && t.FORMTYPE == item.FORMTYPE))
                {
                    currentUserMenus.RemoveAll(t => t.MENUNAME == item.MENUNAME && t.FORMTYPE == item.FORMTYPE);
                    continue;
                }
                var addMenu = RepositoryUser.DbContext.Set<Menu>().Where(t => t.MENUNAME == item.MENUNAME && t.FORMTYPE == item.FORMTYPE).FirstOrDefault();
                currentUser.MENUS.Add(addMenu == null ? item : addMenu);
            }
            foreach (var item in currentUserMenus)
            {
                var removeMenu = RepositoryUser.DbContext.Set<Menu>().Where(t => t.MENUNAME == item.MENUNAME && t.FORMTYPE == item.FORMTYPE).FirstOrDefault();
                currentUser.MENUS.Remove(removeMenu);
            }
            RepositoryUser.Update(currentUser);//更新角色
            return true;
        }

        public void Dispose()
        {
            RepositoryMenu.DbContext.Dispose();
            RepositoryNavigation.DbContext.Dispose();
            RepositoryUser.DbContext.Dispose();
            RepositoryRole.DbContext.Dispose();
        }
    }
}
